package Tydzien1Test;
import static org.junit.Assert.*;

import org.junit.Test;

import Tydzien1.Calculator;


public class CalculatorTest {

	@Test
	public void testAddInt() {
		Calculator instance = new Calculator();
		int exactResult = 3;
		int result = instance.add(2, 1);
		assertEquals(exactResult, result, 0);
	}
	@Test
	public void testAddIntFlow() {
		Calculator instance = new Calculator();
		int exactResult1 = (Integer.MIN_VALUE + Integer.MAX_VALUE - 1);
		int exactResult2 = (Integer.MAX_VALUE + Integer.MIN_VALUE + 1);
		int result1 = instance.add(Integer.MAX_VALUE, Integer.MAX_VALUE);
		int result2 = instance.add(Integer.MIN_VALUE, Integer.MIN_VALUE);
		assertEquals(exactResult1, result1);
		assertEquals(exactResult2, result2);
	}

	@Test
	public void testDifferenceInt() {
		Calculator instance = new Calculator();
		int exactResult = -1;
		int result = instance.difference(2, 3);
		assertEquals(exactResult, result);
	}

	@Test
	public void testDifferenceIntFlow() {
		Calculator instance = new Calculator();
		int exactResult1 = (Integer.MAX_VALUE - Integer.MAX_VALUE + 1);
		int exactResult2 = (Integer.MIN_VALUE + Integer.MIN_VALUE - 1);
		int result1 = instance.difference(Integer.MIN_VALUE, Integer.MAX_VALUE);
		int result2 = instance.difference(Integer.MAX_VALUE, Integer.MIN_VALUE);
		assertEquals(exactResult1, result1);
		assertEquals(exactResult2, result2);
	}
	
	@Test
	public void testMultiplyInt() {
		Calculator instance = new Calculator();
		int exactResult = 4;
		int result = instance.multiply(2, 2);
		assertEquals(exactResult, result);
	}
	
	@Test
	public void testMultiplyIntFlow() {
		Calculator instance = new Calculator();
		// INTMAX * 2k = k * (INTMAX * 2) = k * (INTMAX + INTMAX) = k * -2 = -2k
		int exactResult1 = -2;
		int result1 = instance.multiply(Integer.MAX_VALUE, 2 );
		assertEquals(exactResult1, result1);
		
		// INTMAX * (2k+1) = INTMAX * 2k + INTMAX = INTMAX - 2k
		int exactResult2 = (Integer.MAX_VALUE - 4);
		int result2 = instance.multiply(Integer.MAX_VALUE, 5 );
		assertEquals(exactResult2, result2);
		
		int exactResult3 = 2;
		int result3 = instance.multiply(Integer.MAX_VALUE, -2 );
		assertEquals(exactResult3, result3);
		
		int exactResult4 = (Integer.MIN_VALUE + 1 + 4);
		int result4 = instance.multiply(Integer.MAX_VALUE, -5);
		assertEquals(exactResult4, result4);
		
		// INTMIN * 2k = k * (INTMIN * 2) = k * (INTMIN + INTMIN) = k * 0 = 0
		int exactResult5 = 0;
		int result5 = instance.multiply(Integer.MIN_VALUE, 2 );
		assertEquals(exactResult5, result5);
		
		// INTMIN * (2k+1) = INTMIN * 2k + INTMIN = INTMIN
		int exactResult6 = Integer.MIN_VALUE;
		int result6 = instance.multiply(Integer.MIN_VALUE, 7 );
		assertEquals(exactResult6, result6);
		
		int exactResult7 = 0;
		int result7 = instance.multiply(Integer.MIN_VALUE, -2 );
		assertEquals(exactResult7, result7);
		
		int exactResult8 = Integer.MIN_VALUE;
		int result8 = instance.multiply(Integer.MIN_VALUE, -5);
		assertEquals(exactResult8, result8);
	}
	
	@Test
	public void testDivideInt() {
	Calculator instance = new Calculator();
	int exactResult = 3;
	int result = instance.divide(6, 2);
	assertEquals(exactResult, result);
	}
	
	@Test
	public void testDivideInt0() {
	Calculator instance = new Calculator();
	int exactResult = 0;
	int result = instance.divide(2, 0);
	assertEquals(exactResult, result);
	}
	
	@Test
	public void testAddDouble() {
		Calculator instance = new Calculator();
		double exactResult = 2.9;
		double result = instance.add(2.1, 0.8);
		assertEquals(exactResult, result, 0.000000001);
	}

	@Test
	public void testAddDoubleFlow() {
		Calculator instance = new Calculator();
		double exactResult1 = Double.POSITIVE_INFINITY;
		double exactResult2 = Double.NEGATIVE_INFINITY;
		double result1 = instance.add(Double.MAX_VALUE, Double.MAX_VALUE);
		double result2 = instance.add(-Double.MAX_VALUE, -Double.MAX_VALUE);
		assertEquals(exactResult1, result1, 0);
		assertEquals(exactResult2, result2, 0);
	}
	
	@Test
	public void testDifferenceDouble() {
		Calculator instance = new Calculator();
		double exactResult = 1.3;
		double result = instance.difference(2.1, 0.8);
		assertEquals(exactResult, result, 0.000000001);
	}
	
	@Test
	public void testDifferenceDoubleFlow() {
		Calculator instance = new Calculator();
		double exactResult1 = Double.NEGATIVE_INFINITY;
		double exactResult2 = Double.POSITIVE_INFINITY;
		double result1 = instance.difference(-Double.MAX_VALUE, Double.MAX_VALUE);
		double result2 = instance.difference(Double.MAX_VALUE, -Double.MAX_VALUE);
		assertEquals(exactResult1, result1, 0);
		assertEquals(exactResult2, result2, 0);
	}
	
	@Test
	public void testMultiplyDouble() {
		Calculator instance = new Calculator();
		double exactResult = 1.2;
		double result = instance.multiply(2.4, 0.5);
		assertEquals(exactResult, result, 0.000000001);
	}

	@Test
	public void testMultiplyDoubleFlow() {
		Calculator instance = new Calculator();
		double exactResult1 = Double.POSITIVE_INFINITY;
		double exactResult2 = Double.POSITIVE_INFINITY;
		double exactResult3 = Double.NEGATIVE_INFINITY;
		double result1 = instance.multiply(Double.MAX_VALUE, Double.MAX_VALUE);
		double result2 = instance.multiply(-Double.MAX_VALUE, -Double.MAX_VALUE);
		double result3 = instance.multiply(-Double.MAX_VALUE, Double.MAX_VALUE);
		assertEquals(exactResult1, result1, 0);
		assertEquals(exactResult2, result2, 0);
		assertEquals(exactResult3, result3, 0);
	}
	
	@Test
	public void testDivideDouble() {
	Calculator instance = new Calculator();
	double exactResult = 4.4;
	double result = instance.divide(2.2, 0.5);
	assertEquals(exactResult, result, 0.000000001);
	}
	
	@Test
	public void testDivideDouble0() {
	Calculator instance = new Calculator();
	double exactResult1 = Double.POSITIVE_INFINITY;
	double exactResult2 = Double.NaN;
	double result1 = instance.divide(2.1, 0.0);
	double result2 = instance.divide(0.0, 0.0);
	assertEquals(exactResult1, result1, 0);
	assertEquals(exactResult2, result2, 0);
	}

}
